import time

from tqdm import tqdm

from jiquanquan.sample import pfr_opt, HMMModel


def pre_prepare(in_path, out_path, dic_path, test_text_path, mm_res_path, corpus_cat):
    if corpus_cat == '14':
        # 获取FourteenPfr对象
        tfp = pfr_opt.FourteenPfr(in_path, out_path)
    if corpus_cat == '98':
        # 获取FourteenPfr对象
        tfp = pfr_opt.NinetyEightPfr(in_path, out_path)

    # 获取字典
    dic = tfp.generate_dic(dic_path)
    # 获取测试数据
    test_text = tfp.generate_test_text(test_text_path)
    # 保存分词结果
    fmm_res_file = open(mm_res_path, 'w', encoding='utf-8')
    return dic, test_text, fmm_res_file


def run_fmm(in_path='./docs/corpus/originalData/2014_pfr_corpus.txt',
            out_path='./docs/corpus/tempData/2014_processed_text.txt',
            dic_path='./docs/corpus/tempData/2014_dic.txt',
            test_text_path='./docs/corpus/tempData/2014_test_text.txt',
            mm_res_path='./docs/corpus/resultData/2014_fmm_result.txt',
            corpus_cat='14',
            max_dic_len=5):
    dic, test_text, fmm_res_file = pre_prepare(in_path, out_path, dic_path, test_text_path, mm_res_path, corpus_cat)
    for sentence in tqdm(test_text):
        # 获取到一条语句，对其进行前向匹配
        sen = sentence.strip()
        # 需要保持有序，不能使用set
        words = []
        # 最少一个单词
        max_loop = max_dic_len
        while len(sen) > 0:
            index = 1
            if len(sen) < max_dic_len:
                max_loop = len(sen)
            # 速度很慢
            for i in range(max_loop, 0, -1):
                # 最少为一个中文字符
                tmp = sen[:i]
                if tmp in dic:
                    words.append(tmp)
                    index = i
                    break
            sen = sen[index:]
        if words:
            fmm_res_file.write(' '.join(words) + '\n')


def run_bmm(in_path='./docs/corpus/originalData/2014_pfr_corpus.txt',
            out_path='./docs/corpus/tempData/2014_processed_text.txt',
            dic_path='./docs/corpus/tempData/2014_dic.txt',
            test_text_path='./docs/corpus/tempData/2014_test_text.txt',
            mm_res_path='./docs/corpus/resultData/2014_bmm_result.txt',
            corpus_cat='14',
            max_dic_len=5):
    dic, test_text, bmm_res_file = pre_prepare(in_path, out_path, dic_path, test_text_path, mm_res_path, corpus_cat)
    for sentence in tqdm(test_text):
        # 获取到一条语句，对其进行前向匹配
        sen = sentence.strip()
        # 需要保持有序，不能使用set
        words = []
        max_loop = max_dic_len
        while len(sen) > 0:
            # 表示在字典中不存在
            index = 1
            if len(sen) < max_dic_len:
                max_loop = len(sen)
            for i in range(max_loop, 0, -1):
                # 从后选取窗口大小个文字
                tmp = sen[-i:]
                if tmp in dic:
                    words.append(tmp)
                    index = i
                    break
            remain_len = len(sen) - index
            sen = sen[:remain_len]
        # 不为空
        if words:
            bmm_res_file.write(' '.join(words[::-1]) + '\n')


def run_bdt_mm(fmm_file='./docs/corpus/resultData/2014_fmm_result.txt',
               bmm_file='./docs/corpus/resultData/2014_bmm_result.txt',
               bdt_mm_res_path='./docs/corpus/resultData/2014_bdt_mm_result.txt'):
    "Bidirectional maximum match"
    fmm_res = open(fmm_file, encoding='utf-8').readlines()
    bmm_res = open(bmm_file, encoding='utf-8').readlines()
    bdt_mm_res_file = open(bdt_mm_res_path, 'w', encoding='utf-8')
    min_len = min(len(fmm_res), len(bmm_res))

    for i in tqdm(range(min_len)):
        fmm_segmen_num = len(fmm_res[i].strip().split(' '))
        bmm_segmen_num = len(bmm_res[i].strip().split(' '))
        if fmm_segmen_num < bmm_segmen_num:
            bdt_mm_res_file.write(fmm_res[i])

        elif fmm_segmen_num == bmm_segmen_num:
            if fmm_res[i] == bmm_res[i]:
                bdt_mm_res_file.write(fmm_res[i])
            else:
                # 写入单字较少的
                fmm_segmen = fmm_res[i].strip().split(' ')
                bmm_segmen = bmm_res[i].strip().split(' ')
                f_sin_word_num = sum([1 for i in fmm_segmen if len(i) == 1])
                b_sin_word_num = sum([1 for i in bmm_segmen if len(i) == 1])
                if f_sin_word_num < b_sin_word_num:
                    bdt_mm_res_file.write(fmm_res[i])
                else:
                    bdt_mm_res_file.write(bmm_res[i])
        else:
            bdt_mm_res_file.write(bmm_res[i])


def run_hmm_model(processed_text_path="../docs/corpus/tempData/2014_processed_text.txt",
                  test_text_path="../docs/corpus/tempData/2014_test_text.txt",
                  hmm_res_path='../docs/corpus/resultData/2014_hmm_result.txt'):
    # 记录开始时间
    start = time.time()
    # 依据数据集统计π，A,B这三个参数
    PAI, A, B = HMMModel.trainParameter(processed_text_path)
    # 根据训练得到的模型做测试
    artical = HMMModel.loadArtical(test_text_path)

    # 打印原文
    # print('---------------------------------------原文------------------------------------------------')
    # for line in artical:
    #     print(line)

    # 进行分词
    partiArtical = HMMModel.participle(artical, PAI, A, B)

    # 打印分词结果
    # print('--------------------------------------分词-------------------------------------------------')
    # for line in partiArtical:
    #     print(line)

    hmm_res_file = open(hmm_res_path, 'w', encoding='utf-8')
    # 写出
    for line in tqdm(partiArtical):
        hmm_res_file.write(line.replace("|", " ") + '\n')

    end = time.time()
    print('time span =', end - start, 's')
